package com.wang.springframework.core.convert.converter;

import cn.hutool.core.lang.Assert;

import java.util.Set;

/**
 * @author wangjianhua
 * @Description 通用的转换接口
 * @date 2021/9/7/007 11:03
 **/
public interface GenericConverter {

    /**
     * 返回此转换器可以转换的源类型和目标类型
     * @return 集合
     */
    Set<ConvertiblePair> getConvertibleTypes();


    /**
     *将源对象转换为{@code TypeDescriptor}描述的targetType。
     *@param source 要转换的源对象（可能是{@code null}）
     *@param sourceType 我们从中转换的字段的类型描述符
     *@param targetType 我们要转换到的字段的类型描述符
     *@return 已转换的对象
     */
    Object convert(Object source,Class<?> sourceType,Class<?> targetType);


    /**
     * @author wangjianhua
     * @Description 源到目标类键值对的持有者
     * @date 2021/9/7/007 11:33
     **/
    final class ConvertiblePair{

        private final Class<?> sourceType;
        private final Class<?> targetType;

        public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
            Assert.notNull(sourceType,"SourceType must not be null");
            Assert.notNull(targetType,"TargetType must not be null");
            this.sourceType = sourceType;
            this.targetType = targetType;
        }

        public Class<?> getSourceType() {
            return sourceType;
        }

        public Class<?> getTargetType() {
            return targetType;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
            {
                return true;
            }
            if (obj == null || obj.getClass()!=ConvertiblePair.class)
            {
                return false;
            }
            ConvertiblePair other = (ConvertiblePair) obj;
            return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
        }

        @Override
        public int hashCode() {
            return this.sourceType.hashCode() * 31 + this.targetType.hashCode();
        }
    }
}
